<template>
	<div></div>
</template>

<script>
import ivcs from '../ivcs-sdk';
const IRtc = ivcs.IRtc;
let { LocalStream, MediaStreamFactory, StreamSourceInfo } = IRtc.Base;
export default {
	name: 'WatermarkReplacebackground',
	data() {
		return {
			/*水印背景相关的*/
			cameraCanvas: null,
			cameraContext: null,
			cameraVideo: null,
			isCameraRendering: null,
			backgroundImage: null,
			backgroundCanvas: null,
			backgroundContext: null,
			watermarkImage: null,
			watermarkCanvas: null,
			watermarkContext: null,
			canvas: null,
			context: null,
			frameRate: 15,
			lastRenderTime: Date.now(),
			localCustomizedStream: null,
			customizedLocalStream: null
		};
	},
	props: ['aitype', 'isReplaceBackground', 'isAddWatermark', 'resolution', 'width', 'height', 'Red', 'Green', 'Blue'],
	mounted() {},
	methods: {
		/*创建本地媒体流带水印和背景*/
		async createCustomizedStream() {
			return new Promise((resolve, reject) => {
				console.log('start create water stream');
				const cameraVideo = document.getElementById('cameraVid');
				cameraVideo.pause();

				//main canvas for local stream output
				this.canvas = document.createElement('canvas');
				this.canvas.width = this.width;
				this.canvas.height = this.height;
				if (this.canvas.getContext) {
					this.context = this.canvas.getContext('2d');
				}
				//canvas with background image
				this.backgroundCanvas = document.createElement('canvas');
				this.backgroundCanvas.width = this.width;
				this.backgroundCanvas.height = this.height;
				if (this.backgroundCanvas.getContext) {
					this.backgroundContext = this.backgroundCanvas.getContext('2d');
					this.backgroundImage = new Image();
					this.backgroundImage.src = localStorage.getItem('bgimage'); //'static/image/background.jpg';
				}
				console.log(this.backgroundImage.src);
				//canvas with watermark image
				this.watermarkCanvas = document.createElement('canvas');
				this.watermarkCanvas.width = this.width;
				this.watermarkCanvas.height = this.height;
				if (this.watermarkCanvas.getContext) {
					this.watermarkContext = this.watermarkCanvas.getContext('2d');
					this.watermarkImage = new Image();
					this.watermarkImage.src = localStorage.getItem('watermarkimage'); //'static/image/water6402.png';
				}
				this.isCameraRendering = false;

				let audio = {
					deviceId: undefined, //Do not provide deviceId if source is not "mic".
					source: 'mic' //Values could be "mic", "screen-cast", "file" or "mixed".
				};

				let video = {
					resolution: this.resolution, //The Resolution defines the size of a rectangle.
					frameRate: this.frameRate,
					deviceId: undefined, //Do not provide deviceId if source is not "camera".
					source: 'camera' //values could be "camera", "screen-cast", "file" or "mixed".
				};
				let videoSource = 'camera'; //Video source info. Accepted values are: "camera", "screen-cast", "file", "mixed" or undefined.
				let audioSource = 'mic'; //Audio source info. Accepted values are: "mic", "screen-cast", "file", "mixed" or undefined.
				let streamSourceInfo = new StreamSourceInfo(audioSource, videoSource);
				let mediaStreamDeviceConstraints = {
					audio: audio,
					video: video
				};
				var self = this;
				console.log('water mark stream options', mediaStreamDeviceConstraints);
				MediaStreamFactory.createMediaStream(mediaStreamDeviceConstraints)
					.then(function(mediaStream) {
						console.log(mediaStream);
						return new LocalStream(mediaStream, streamSourceInfo, { type: self.aitype });
					})
					.catch(function(error) {
						console.log(error);
						reject(error);
					})
					.then(function(localCustomizedStream) {
						console.log(localCustomizedStream);
						self.handleCameraStream(
							localCustomizedStream,
							self.canvas,
							resp => {
								resolve(resp);
							},
							error => {
								reject(error);
							}
						);
					})
					.catch(function(error) {
						console.log(error);
						reject(error);
					});
			});
		},

		/*处理camera流*/
		handleCameraStream(stream, canvas, onSuccess, onFailure) {
			//create canvas to draw camera stream
			this.cameraCanvas = document.createElement('canvas');
			this.cameraCanvas.width = this.width;
			this.cameraCanvas.height = this.height;
			this.cameraContext = this.cameraCanvas.getContext('2d');

			var _cStream = canvas.captureStream(this.frameRate);
			//add audio track to cavansstream
			var audioTrack = stream.mediaStream.getAudioTracks()[0];
			_cStream.addTrack(audioTrack);
			console.log('camera canvas stream created ', _cStream, ' audio ', _cStream.getAudioTracks(), ' video ', _cStream.getVideoTracks());

			const cameraVideo = document.getElementById('cameraVid');
			cameraVideo.srcObject = stream.mediaStream;
			cameraVideo.onloadedmetadata = () => cameraVideo.play();
			this.isCameraRendering = true;
			var inited = false;
			var self = this;
			cameraVideo.addEventListener('timeupdate', function(ev) {
				if (!inited) {
					cameraVideo.style.visibility = 'hidden';
					inited = true;
					self.cameraVideo = cameraVideo;
				}
				self.RenderCameraFrame();
			});
			this.createCustomizedLocalStream(_cStream, (err, localCameraStream) => {
				self.localCustomizedStream = localCameraStream;
				console.log('localCustomizedStream', localCameraStream);
				if (err) {
					onFailure(err);
				} else {
					onSuccess(localCameraStream);
				}
			});
		},

		/*创建处理后的流*/
		createCustomizedLocalStream(mediaStream, callback) {
			let videoSource = 'camera';
			let audioSource = 'mic';
			let streamSourceInfo = new StreamSourceInfo(audioSource, videoSource);
			this.customizedLocalStream = new LocalStream(mediaStream, streamSourceInfo, { type: this.aitype });
			if (typeof callback === 'function') {
				callback(null, this.customizedLocalStream);
			}
		},

		/*实时渲染*/
		RenderCameraFrame() {
			if (this.isCameraRendering) {
				if (Date.now() - this.lastRenderTime > 1000.0 / this.frameRate) {
					//prepare video from from camera
					this.cameraContext.clearRect(0, 0, this.width, this.height);
					this.cameraContext.drawImage(this.cameraVideo, 0, 0);
					//prepare background image
					if (this.isReplaceBackground) {
						this.backgroundContext.drawImage(this.backgroundImage, 0, 0, this.backgroundImage.width, this.backgroundImage.height, 0, 0, this.width, this.height);
					}
					//prepare watermark image
					if (this.isAddWatermark) {
						this.watermarkContext.drawImage(this.watermarkImage, 0, 0, this.watermarkImage.width, this.watermarkImage.height, 0, 0, this.width, this.height);
					}

					this.context.clearRect(0, 0, this.width, this.height);
					this.context.putImageData(this.cutOut(this.cameraContext, this.backgroundContext, this.watermarkContext, this.isReplaceBackground, this.isAddWatermark), 0, 0);
					this.lastRenderTime = Date.now();
				}
				requestAnimationFrame(this.RenderCameraFrame);
			}
		},

		/*裁剪*/
		cutOut(ctxVideo, ctxBkg, ctxWtmk, replaceBackground, addWatermark) {
			//const GREEN_THRESHOLD = 100;
			//Red  Green Blue
			// console.log('backimage rgb=='+this.Red+":"+this.Green+":"+this.Blue);

			let frameData = ctxVideo.getImageData(0, 0, this.width, this.height),
				backgroundData = ctxBkg.getImageData(0, 0, this.width, this.height),
				watermarkData = ctxWtmk.getImageData(0, 0, this.width, this.height),
				len = frameData.data.length / 4;
			for (let i = 0; i < len; i++) {
				if (replaceBackground) {
					if (frameData.data[i * 4 + 0] <= this.Red && frameData.data[i * 4 + 1] >= this.Green && frameData.data[i * 4 + 2] <= this.Blue) {
						frameData.data[i * 4 + 0] = backgroundData.data[i * 4 + 0];
						frameData.data[i * 4 + 1] = backgroundData.data[i * 4 + 1];
						frameData.data[i * 4 + 2] = backgroundData.data[i * 4 + 2];
					}
				}

				if (addWatermark) {
					if (watermarkData.data[i * 4 + 3] != 0) {
						frameData.data[i * 4 + 0] = watermarkData.data[i * 4 + 0];
						frameData.data[i * 4 + 1] = watermarkData.data[i * 4 + 1];
						frameData.data[i * 4 + 2] = watermarkData.data[i * 4 + 2];
					}
				}
			}
			return frameData;
		},
		/** 停止水印流 */
		stopCustomizedLocalStream() {
			return new Promise((resolve, reject) => {
				try {
					const cameraVideo = document.getElementById('cameraVid');
					const stream = cameraVideo?.srcObject || null;
					if (stream) {
						const tracks = stream.getTracks();
						tracks.forEach(track => {
							track.stop();
						});
						cameraVideo.srcObject = null;
						resolve('ok');
					} else {
						resolve('ok');
					}
				} catch (error) {
					console.log('stopCustomizedLocalStream:', error);
					reject(error);
				}
			});
		}
	}
};
</script>

<style scoped></style>
